<template>
  <div class="channel-edit">
    <van-cell title="我的频道" :border="false">
        <template #default>
            <van-button type="warning" class="edit-btn" plain round size="mini" @click="isEditShow = !isEditShow">{{isEditShow ? '完成' : '编辑'}}</van-button>
        </template>
    </van-cell>
    <van-grid :gutter="10">
        <van-grid-item
        v-for="(channel, index) in myChannels" :key="index"
        class="channel-item"
        @click="onClickMyChannel(channel,index)"
        >
            <template #icon>
                <van-icon name="close" v-show="isEditShow && index !== 0"/>
            </template>
            <template #text>
                <span :class="{isActive: active === index}" class="text">{{ channel.name }}</span>
            </template>
        </van-grid-item>
    </van-grid>
    <van-cell title="频道推荐" :border="false">
    </van-cell>
    <van-grid :gutter="10" class="recome-grid">
        <van-grid-item :text="channel.name" icon="plus" v-for="(channel, index) in recommChannel" :key="index" class="channel-item" @click="onAddChannel(channel)"/>
    </van-grid>
  </div>
</template>

<script>
/*
  目标2：在编辑遮罩中，展示首页当前选中的频道
  1. 将父组件中<van-tabs>上绑定的当前选中索引变量active，传递给遮罩层
  2. 在子组件中设置动态样式（class style）去区别当前首页显示的频道
  当设置动态class发现，无法影响ui组件中的某一个小元素样式，那么想办法将该小元素以插槽的形式显式的提取出来，再设置动态class
*/
/*
  目标3：获取并展示所有频道接口
  获取：
  1. 查阅接口文档，并封装对应的接口，在index.js输出
  2. 通过分析，为了最大的保证用户体验，见获取全部频道的数据方法写在home.vue父组件中
  3. 在父组件中将全部频道数据传递给子组件
  展示：
  1. 通过计算属性 => 推荐频道 = 频道总数 - 我的频道 => 得到一个推荐频道的计算属性
  2. 把该计算属性数组遍历到推荐频道的页面上去

  /*
  目标4：添加频道
  1. 给推荐频道中的每一个小频道绑定点击事件
  2. 通过点击事件将当前的频道元素对象通过push的方式添加到我的频道中

  为什么我们还没有做删除，但是频道推荐中的内容就自动减少了？ - 通过计算属性，可以自动的进行推荐频道的内容删除

  目标5： 编辑频道的操作
  切换编辑与跳转状态
  1. 创建一个状态变量，通过改变了来影响 删除图标、编辑/完成按钮 的展示
  2. 给编辑/完成 按钮绑定点击事件 来实现状态变量的切换
  3. 我的频道中，推荐 不可以出现删除图标

  切换频道逻辑
  1. 给我的频道中的每一个小频道绑定点击事件
  2. 通过判断状态值isEditShow的当前模式为false时，则进行跳转切换操作
  3. 通过$emit()的方式触发父组件的自定义事件，来实现active状态的切换
  4. 主动的关闭编辑频道弹框遮罩

    删除频道逻辑
  现象: 1. 在编辑状态下，点击 非推荐 的频道，在我的频道中删除，在频道推荐的列表中显示
       2.  在首页，同样被删除的频道不显示
       3. 删除其他非高亮频道时，不会影响高亮频道的重新选择
       4. 删除高亮频道时，会将高亮的频道切换到往左数第一个的频道位置
  1. 在频道点击事件的isEditShow为true（编辑状态时），触发我的频道列表的删除操作（splice）
  2. 推荐频道列表是否需要做添加操作 - 答：不需要做，计算属性会自动帮助我们完成
  3. 首页的channels频道列表是否需要做删除操作 - 答： 不需要，因为channels和myChannels是共享堆内存中的数据的，所以不需要
  4. 如果删除的 那个元素所在的索引 小等于 当前激活频道的索引 那么需要将 当前的激活索引值(active)-1
  5. 当删除某个频道时，编辑弹出层自动关闭了 - 通过新增参数来判断是否关闭

  目标6：持久化数据
  描述：有登录状态时，调用接口和获取新增修改查询的数据， 无登录状态时，通过本地缓存获取数据
  添加频道时的数据持久化
  1. 通过用户的登录状态 （通过store.state.user.token是否存在） 来判断是调用接口还是本地缓存
  2. 获取token的方式 1 - this.$store.state.user.token  2 - 通过VUEX内置的方法mapState来直接获取user

    首页获取频道列表持久化
  1. 判断用户是否登录，如果已登录则调用接口获取列表
  2. 如果用户没登录，则尝试去本地存储中获取数据
  3. 如果本地存储没有数据，则调用接口获取列表（headers中没有token数据）

  总结=>
  如果 有user.token 或者 没有本地缓存 => 调用接口
  反之其他情况则拿 取缓存数据
*/
import { mapState } from 'vuex'
import { setItem } from '../../../utils/storage.js'
import { addUserChannelAPI, deleteUserChannelAPI } from '../../../api/index.js'
export default {
  name: 'ChannelEdit',
  props: {
    myChannels: {
      type: Array,
      default: () => []
    },
    allChannels: {
      type: Array,
      default: () => []
    },
    active: {
      type: Number,
      default: 0
    }
  },
  computed: {
    // eslint-disable-next-line no-undef
    ...mapState(['user']),
    recommChannel () {
      // 推荐频道需要是全部中有但是我的频道中没有，总数为25
    //   const templist = this.allChannels.filter(channel => {
    //     const index = this.myChannels.findIndex(mychannel => {
    //       return mychannel.id === channel.id
    //     })
    //     // 如果index为-1 表示我的频道中没有这个数据，否则表示有
    //     // 如果为-1就将这个数据项返回
    //     return index === -1
    //   })
    //   return templist
    // 使用lodash解决 ,lodash有时会返回伪数组
      return [...this.$_.differenceBy(this.allChannels, this.myChannels, 'id')]
    }
  },
  data () {
    return {
      myChannelsClone: this.myChannels,
      isEditShow: false // 控制close图标的显示瑜隐藏
    }
  },
  methods: {
    // 添加频道
    // 当登录时调用接口将数据传给接口，未登录则将数据存储到本地存储
    async onAddChannel (channel) {
      this.myChannelsClone.push(channel)
      if (this.user.token) {
        try {
          await addUserChannelAPI({
            id: channel.id,
            req: this.myChannels.length
          })
          this.$toast.success('添加成功')
        } catch (error) {
          this.$toast.fail('添加失败')
          console.log(error)
        }
      } else {
        setItem('TOUTIAO_CHANNELS', this.myChannels)
      }
    },
    // 点击我的 频道，在编辑状态下是删除，否则就是频道切换
    async onClickMyChannel (channel, index) {
      // 页面是页面，逻辑是逻辑，做页面上的某个条件判断时，既需要该页面，也需要添加相应的代码逻辑
      // 如果索引为0 ，表示是推荐频道，不可删除
      if (index === 0) {
        return
      }
      if (this.isEditShow) {
      // 编辑状态，点击删除频道
        this.myChannelsClone.splice(index, 1)
        // 如果删除的是选中状态之后的不做操作，删除之前的让当前选中索引的前一个选中
        // 因为这个方法与切换频道方法是同一个，所以增加一个参数用于区分是否切换频道
        if (index <= this.active) {
          this.$emit('updateChannel', this.active - 1, true)
        }
        if (this.user.token) {
          try {
            await deleteUserChannelAPI(channel.id)
            this.$toast.success('删除成功')
          } catch (error) {
            this.$toast.fail('删除失败')
            console.log(error)
          }
        } else {
          setItem('TOUTIAO_CHANNELS', this.myChannels)
        }
      } else {
      // 非编辑状态，点击切换频道
        this.$emit('updateChannel', index)
      }
    }
  }

}
</script>

<style lang="less" scoped>
.channel-edit {
    .van-cell__title {
        font-size: 32px;
        color: #333;
    }
    .edit-btn {
        width: 123px;
        height: 69px;
    }
    .recome-grid {
        :deep(.van-grid-item__content) {
            flex-direction: row;
            .van-icon-plus {
                margin-right: 6px;
                font-size: 24px;
                color: #222;
            }
        }

    }
    .channel-item{
        width: 160px;
        height: 86px;

        :deep(.van-grid-item__content){
            background-color: #f4f5f6;
            white-space: nowrap;

            .isActive {
                color: red !important;
             }
            .van-grid-item__text, .text{
                font-size: 28px;
                color:#222;
                margin-top: 0;
            }
            .van-grid-item__icon-wrapper {
                position: unset;
            }
            .van-icon-close {
                position: absolute;
                right: -10px;
                top: -10px;
                font-size: 30px;
                color: #cacaca;
            }
    }
    }

}
</style>
